package web.beans;
 
import ejb.entities.Event;
import ejb.entities.Invitation;
import ejb.facade.EventFacade;
import ejb.facade.InvitationFacade;
import ejb.facade.WeatherFacade;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.application.FacesMessage;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
import javax.faces.context.FacesContext;
import javax.inject.Inject;
 
import org.primefaces.event.ScheduleEntryMoveEvent;
import org.primefaces.event.ScheduleEntryResizeEvent;
import org.primefaces.event.SelectEvent;
import org.primefaces.model.DefaultScheduleEvent;
import org.primefaces.model.DefaultScheduleModel;
import org.primefaces.model.ScheduleEvent;
import org.primefaces.model.ScheduleModel;
 
@ViewScoped
@Named("homeBean")
public class HomeBean implements Serializable {
    
    @Inject
    private Login login;
           
    private ScheduleModel eventModel;
     
    private ScheduleModel lazyEventModel;
 
    private ScheduleEvent event = new DefaultScheduleEvent();
    
    @EJB
    private EventFacade evFacade;
    @EJB
    private InvitationFacade inFacade; 
    @EJB
    private WeatherFacade weaFacade;
 
    private boolean eventSelected;
    
    @PostConstruct
    public void init() {
        eventModel = new DefaultScheduleModel();
        this.eventSelected = false;
        
        //Load Event with user as owner
        for (Event s : evFacade.findEventByCreator(login.getUser())){
			if (s!=null && !"".equals(s.getTitle()) && s.getDateTimeEnd()!=null && s.getDateTimeStart()!=null){
                             DefaultScheduleEvent newEvent = new DefaultScheduleEvent(s.getTitle(), s.getDateTimeStart(), s.getDateTimeEnd());
                             newEvent.setData(s.getIdEvent());
                             newEvent.setStyleClass("public-event-crea");
                             eventModel.addEvent(newEvent);                            
                        }
	}   
        
        //Load event with invitation accepted
                for (Invitation s : inFacade.findInvitationByUser(login.getUser())) {  
                    if (s!=null && !"".equals(s.getEvent().getTitle()) && s.getEvent().getDateTimeEnd()!=null && s.getEvent().getDateTimeStart()!=null){
                        if("A".equals(s.getInvstate())){
                             DefaultScheduleEvent newEvent = new DefaultScheduleEvent(s.getEvent().getTitle(), s.getEvent().getDateTimeStart(), s.getEvent().getDateTimeEnd());
                             newEvent.setData(s.getEvent().getIdEvent());
                             newEvent.setStyleClass("public-event-inv"); 
                             eventModel.addEvent(newEvent);
                        }
                    }
	}
           login.setFirstAccessUp(false);
    }
        
    //GETTER Functions

    public InvitationFacade getInFacade() {
        return inFacade;
    }

    public Login getLogin() {
        return login;
    }

    public EventFacade getevFacade() {
        return evFacade;
    }
    
    public ScheduleModel getEventModel() {
        return eventModel;
    }
     
    public ScheduleModel getLazyEventModel() {
        return lazyEventModel;
    }

    //SETTER Functions
    
    public void setInFacade(InvitationFacade inFacade) {
        this.inFacade = inFacade;
    }

    public void setLogin(Login login) {
        this.login = login;
    }

    public void setEventModel(ScheduleModel eventModel) {
        this.eventModel = eventModel;
    }

    public void setLazyEventModel(ScheduleModel lazyEventModel) {
        this.lazyEventModel = lazyEventModel;
    }

    public void setevFacade(EventFacade evFacade) {
        this.evFacade = evFacade;
    }
     
    //BEAN Functions
    
    public Date getRandomDate(Date base) {
        Calendar date = Calendar.getInstance();
        date.setTime(base);
        date.add(Calendar.DATE, ((int) (Math.random()*30)) + 1);    //set random day of month
         
        return date.getTime();
    }
     
    public Date getInitialDate() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), Calendar.FEBRUARY, calendar.get(Calendar.DATE), 0, 0, 0);
         
        return calendar.getTime();
    }
     
    private Calendar today() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH), calendar.get(Calendar.DATE), 0, 0, 0);
 
        return calendar;
    }
     
    private Date previousDay8Pm() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) - 1);
        t.set(Calendar.HOUR, 8);
         
        return t.getTime();
    }
     
    private Date previousDay11Pm() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) - 1);
        t.set(Calendar.HOUR, 11);
         
        return t.getTime();
    }
     
    private Date today1Pm() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.HOUR, 1);
         
        return t.getTime();
    }
     
    private Date theDayAfter3Pm() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.DATE, t.get(Calendar.DATE) + 2);     
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.HOUR, 3);
         
        return t.getTime();
    }
 
    private Date today6Pm() {
        Calendar t = (Calendar) today().clone(); 
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.HOUR, 6);
         
        return t.getTime();
    }
     
    private Date nextDay9Am() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.AM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) + 1);
        t.set(Calendar.HOUR, 9);
         
        return t.getTime();
    }
     
    private Date nextDay11Am() {
        Calendar t = (Calendar) today().clone();
        t.set(Calendar.AM_PM, Calendar.AM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) + 1);
        t.set(Calendar.HOUR, 11);
         
        return t.getTime();
    }
     
    private Date fourDaysLater3pm() {
        Calendar t = (Calendar) today().clone(); 
        t.set(Calendar.AM_PM, Calendar.PM);
        t.set(Calendar.DATE, t.get(Calendar.DATE) + 4);
        t.set(Calendar.HOUR, 3);
         
        return t.getTime();
    }
     
    public ScheduleEvent getEvent() {
        return event;
    }
 
    public void setEvent(ScheduleEvent event) {
        this.event = event;
    }
         
    public void moveToAddEvent(){
        login.setEventSelected(this.event.getTitle(), this.event.getStartDate(), this.event.getEndDate());
        redirect("user_addNewEvent.xhtml");
    }
     
    public void onEventSelect(SelectEvent selectEvent) {
        event = (ScheduleEvent) selectEvent.getObject();
        this.eventSelected = true;
    }
     
    public void onDateSelect(SelectEvent selectEvent) {
        Date correctDate = (Date) selectEvent.getObject();
        Calendar c = Calendar.getInstance(); 
        c.setTime(correctDate); 
        c.add(Calendar.DATE, 1);
        correctDate = c.getTime();
        correctDate = login.fromDateTimetoDate(correctDate);
        event = new DefaultScheduleEvent("", correctDate, correctDate);
        this.eventSelected = false;
    }
     
    public void onEventMove(ScheduleEntryMoveEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event moved", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());    
        addMessage(message);
    }
     
    public void moveToEditEvent(){
        login.setEventSelected((int)event.getData());
        redirect("user_addNewEvent.xhtml");
    }
    
    public void onEventResize(ScheduleEntryResizeEvent event) {
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_INFO, "Event resized", "Day delta:" + event.getDayDelta() + ", Minute delta:" + event.getMinuteDelta());
         
        addMessage(message);
    }
     
    private void addMessage(FacesMessage message) {
        FacesContext.getCurrentInstance().addMessage(null, message);
    }
    
    public void goToNewEvent(){
            redirect("user_addNewEvent");
        }
        
        public void goToManagerEvent(){
            redirect("user_eventManager");
        }
        
        public void goToNotifyCenter(){
            redirect("user_notifyCenter");
        }
        
        public void goToMaps(){
            redirect("user_map");
        }
        
        public void redirect(String outcome) {
            FacesContext facesContext = FacesContext.getCurrentInstance();
            facesContext.getApplication().getNavigationHandler().handleNavigation(facesContext, null, outcome);
        }       
                
        public void closeNotify(){
            this.login.setNotifyUp(false);
        }
                
        public String getWelcomeMessage(){
            return "Welcome "+login.getUserFullName()+", have new notifications!!!";
        }
        
        public boolean isEventSelected(){
            return this.eventSelected;
        }
}